package com.example.demo.service.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.mapper.*;
import com.example.demo.pojo.Accounts.FundAccounts;
import com.example.demo.pojo.Accounts.UserFundAccounts;
import com.example.demo.pojo.Competitions.*;
import com.example.demo.pojo.R;
import com.example.demo.service.VipCompetitionService;
import com.example.demo.utils.RandomUtils;
import com.example.demo.utils.TokenUtil.decryptToken;
import com.example.demo.utils.TokenUtil.spiltUtils;
import com.example.demo.utils.UserUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.example.demo.utils.ConstantUtils.PASSCODE_LENGTH;
import static com.example.demo.utils.ConstantUtils.UN_FINISH;

@Service
@Slf4j
public class VipCompetitionServiceImpl extends ServiceImpl<CompetitionMapper, Competitions> implements VipCompetitionService {
    @Resource
    private CompetitionMapper competitionMapper;
    @Resource
    private UserCompetitionMapper userCompetitionMapper;
    @Resource
    private FundAccountMapper fundAccountMapper;
    @Autowired
    private InvitedUserIdsMapper invitedUserIdsMapper;

    @Resource
    private UserFundAccountMapper userFundAccountMapper;

    @Autowired
    private CompetitionPasscodeMapper competitionPasscodeMapper;
    @Resource
    private UserUtil userUtil;


    @Override
    public R<Map<String, String>> creatCompetition(Competitions competitions, String token) {
        //获取当前用户的真实姓名
        String decrypt = decryptToken.decrypt(token);
        String userName = spiltUtils.getUserName(decrypt);
        Integer userId = userUtil.getUserId(userName);
        //判断是否实名
        boolean realNameAuthentication = userUtil.getRealNameAuthentication(userId);
        if (!realNameAuthentication) {
            return R.failed("你还未进行实名认证！");
        }
        String realName = userUtil.getRealName(userName);
        competitions.setCreatUserName(realName);
        competitions.setStartDate(new Date());
        competitions.setVipId(userId);
        competitions.setStatus(UN_FINISH);
        int insert = competitionMapper.insert(competitions);
        if (insert > 0) {
            // 生成包含当前时间戳和随机字符串的口令
            String passcode = RandomUtils.generateRandomPasscode(PASSCODE_LENGTH);
            //新增口令表
            CompetitionPasscode competitionPasscode = new CompetitionPasscode();
            competitionPasscode.setCompetitionId(competitions.getCompetitionId());
            competitionPasscode.setPasscode(passcode);
            competitionPasscode.setCreateTime(new Date());
            int competitionPasscodeInsert = competitionPasscodeMapper.insert(competitionPasscode);
            if (competitionPasscodeInsert > 0) {
                Map<String,String> map = new HashMap<>();
                map.put("passcode",passcode);
                return R.success("比赛创建成功，并生成了口令！",map);
            }
            return R.failed("比赛创建成功，但口令生成失败！");
        }
        return R.failed("比赛创建失败！");
    }

    @Override
    @Transactional
    public void vipJoinCompetition(Integer userId, Integer id) {
        try {
            // 从数据库中获取比赛信息(比赛id)
            QueryWrapper<Competitions> competitionsQueryWrapper = new QueryWrapper<>();
            competitionsQueryWrapper.eq("competition_id", id);
            Competitions competitions = competitionMapper.selectOne(competitionsQueryWrapper);
            //判断是否实名
            boolean realNameAuthentication = userUtil.getRealNameAuthentication(userId);
            if (!realNameAuthentication) {
                R.failed("你还未进行实名认证！");
                return;
            }
            // 检查是否获取到比赛信息
            if (competitions == null) {
                return;
            }

            // 获取比赛的截止日期
            Date deadline = competitions.getEndDate();

            // 获取当前日期
            Date now = new Date();

            // 判断比赛截止日期是否到期
            if (now.after(deadline)) {
                return;
            }
            //判断是否退过赛
            QueryWrapper<UserCompetitions> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("competition_id", id)
                    .eq("real_name", userUtil.getRealNameById(userId))
                    .eq("status", "退赛");
            UserCompetitions userCompetitionPojo = userCompetitionMapper.selectOne(queryWrapper);
            if (userCompetitionPojo != null) {
                userCompetitionPojo.setStatus("参赛");
                int update = userCompetitionMapper.updateById(userCompetitionPojo);
                if (update > 0) {
                    //生成平台比赛账户
                    FundAccounts fundAccount = new FundAccounts();
                    fundAccount.setAccountId(id);
                    fundAccount.setUserId(userId);
                    fundAccount.setBankAccount("股票账户");
                    fundAccount.setTotalAsset(BigDecimal.ZERO);
                    fundAccount.setAvailableFund(BigDecimal.ZERO);
                    fundAccount.setFrozenFund(BigDecimal.ZERO);
                    fundAccount.setPositionProfitLoss(BigDecimal.ZERO);
                    fundAccount.setPositionValue(BigDecimal.ZERO);
                    fundAccountMapper.insert(fundAccount);
                    //创建银行账户
                    UserFundAccounts userFundAccount = new UserFundAccounts();
                    userFundAccount.setUserAccountId(id);
                    userFundAccount.setUserId(userId);
                    userFundAccount.setUserBankAccount("银行账户");
                    userFundAccount.setUserTotalAsset(BigDecimal.ZERO);
                    userFundAccount.setAvailableFund(BigDecimal.ZERO);
                    userFundAccountMapper.insert(userFundAccount);
                    return;
                }
            }
            UserCompetitions userCompetition = new UserCompetitions();
            userCompetition.setRealName(userUtil.getRealNameById(userId));
            userCompetition.setUserId(userId);
            userCompetition.setCompetitionId(id);
            userCompetition.setStatus("参赛");
            int insert = userCompetitionMapper.insert(userCompetition);
            if (insert > 0) {
                //生成平台比赛账户
                FundAccounts fundAccount = new FundAccounts();
                fundAccount.setAccountId(id);
                fundAccount.setUserId(userId);
                fundAccount.setBankAccount("股票账户");
                fundAccount.setTotalAsset(BigDecimal.ZERO);
                fundAccount.setAvailableFund(BigDecimal.ZERO);
                fundAccount.setFrozenFund(BigDecimal.ZERO);
                fundAccount.setPositionProfitLoss(BigDecimal.ZERO);
                fundAccount.setPositionValue(BigDecimal.ZERO);
                fundAccountMapper.insert(fundAccount);
                //创建银行账户
                UserFundAccounts userFundAccount = new UserFundAccounts();
                userFundAccount.setUserAccountId(id);
                userFundAccount.setUserId(userId);
                userFundAccount.setUserBankAccount("银行账户");
                userFundAccount.setUserTotalAsset(BigDecimal.ZERO);
                userFundAccount.setAvailableFund(BigDecimal.ZERO);
                userFundAccountMapper.insert(userFundAccount);
            }
        } catch (Exception e) {
            log.error("VIP加入比赛失败: ", e);
            R.failed("参赛失败");
        }
    }

    @Override
    @Transactional
    public void vipOutJoinCompetition(Integer userId, Integer id) {
        try {
            String realName = userUtil.getRealNameById(userId);
            UpdateWrapper<UserCompetitions> updateWrapper = new UpdateWrapper<>();
            UserCompetitions userCompetitions = new UserCompetitions();
            userCompetitions.setStatus("退赛");
            updateWrapper.eq("competition_id", id).eq("real_name", realName);
            int update = userCompetitionMapper.update(userCompetitions, updateWrapper);
            if (update > 0) {
                //删除银行账户信息
                QueryWrapper<UserFundAccounts> userFundAccountQueryWrapper = new QueryWrapper<>();
                userFundAccountQueryWrapper.eq("user_account_id", id).eq("user_bank_account", "银行账户");
                userFundAccountMapper.delete(userFundAccountQueryWrapper);
                //删除平台账户
                QueryWrapper<FundAccounts> fundAccountQueryWrapper = new QueryWrapper<>();
                fundAccountQueryWrapper.eq("account_id", id).eq("bank_account", "股票账户");
                fundAccountMapper.delete(fundAccountQueryWrapper);
            }
        } catch (Exception e) {
            log.error("VIP退出比赛失败: ", e);
            R.failed("退出比赛失败");
        }
    }


    @Override
    @Transactional
    public R<T> manageInvitedUsers(String token, Integer competitionId, List<Integer> userIds, String isInviting) {
        try {
            // 检查比赛是否存在
            if (competitionMapper.selectById(competitionId) == null) {
                log.warn("比赛不存在，competitionId: {}", competitionId); // 添加日志记录
                return R.failed("比赛不存在！");
            }

            // 获取已经被邀请的用户列表
            List<InvitedUserIds> existingInvites = getExistingInvites(competitionId, userIds);

            try {
                if ("true".equals(isInviting)) {
                    inviteUsers(competitionId, userIds, existingInvites);
                } else {
                    cancelInvitations(competitionId, userIds);
                }
            } catch (Exception e) {
                log.error("管理邀请时发生错误: ", e); // 异常日志记录
                return R.failed("邀请操作失败！");
            }

            return R.success("操作成功！");
        } catch (Exception e) {
            log.error("管理邀请时发生错误: ", e);
            return R.failed("邀请操作失败");
        }
    }

    @Override
    public R<T> removeCompetition(String token, Integer id) {
        return null;
    }

    @Override
    public R<List<VipCompetitionDetail>> getCreatCompetitions(String token) {
        //获取当前用户的id
        String decrypt = decryptToken.decrypt(token);
        String userName = spiltUtils.getUserName(decrypt);
        Integer userId = userUtil.getUserId(userName);
        //查询关联比赛
        List<VipCompetitionDetail> creatCompetitionByUserId = competitionMapper.getCreatCompetitionByUserId(userId);
        return R.success(creatCompetitionByUserId);
    }

    private void inviteUsers(Integer competitionId, List<Integer> userIds, List<InvitedUserIds> existingInvites) {
        for (Integer userId : userIds) {
            if (isUserAlreadyInvited(userId, existingInvites)) {
                synchronized (this) {
                    if (isUserAlreadyInvited(userId, existingInvites)) {
                        processInvitation(competitionId, userId);
                    }
                }
            } else {
                logAlreadyParticipating(userId);
            }
        }
    }

    private void cancelInvitations(Integer competitionId, List<Integer> userIds) {
        for (Integer userId : userIds) {
            synchronized (this) {
                removeInvitation(competitionId, userId);
            }
        }
    }

    private void processInvitation(Integer competitionId, Integer userId) {
        InvitedUserIds newUser = new InvitedUserIds();
        newUser.setCompetitionId(competitionId);
        newUser.setUserId(userId);
        invitedUserIdsMapper.insert(newUser);
        vipJoinCompetition(userId, competitionId);
    }

    private void removeInvitation(Integer competitionId, Integer userId) {
        QueryWrapper<InvitedUserIds> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("competition_id", competitionId).eq("user_id", userId);
        invitedUserIdsMapper.delete(queryWrapper);
        vipOutJoinCompetition(userId, competitionId);
    }

    private List<InvitedUserIds> getExistingInvites(Integer competitionId, List<Integer> userIds) {
        // 构建查询条件，查询指定比赛中已经存在的邀请
        QueryWrapper<InvitedUserIds> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("competition_id", competitionId).in("user_id", userIds);
        return invitedUserIdsMapper.selectList(queryWrapper);
    }

    private boolean isUserAlreadyInvited(Integer userId, List<InvitedUserIds> existingInvites) {
        if (existingInvites.size() == 0) {
            return true;
        }
        for (InvitedUserIds invite : existingInvites) {
            int Id = invite.getUserId();
            if (Id == userId) {
                return false; // 用户已经在邀请列表中
            }
        }
        return true; // 用户不在邀请列表中
    }


    private void logAlreadyParticipating(Integer userId) {
        // 记录已经参加比赛的用户日志
        String realName = userUtil.getRealNameById(userId);
        log.info(realName + "，已经参与比赛！");
    }


}
